﻿/** 三国战记整合脚本(UTF-8 with BOM)
  功能根据各人不同,比较复杂.
  fbas模拟器暂未设定固有功能
  游聚平台连发,静音切换,热键中断切换
  
  By setycyas @2022-11-23
*/

/** 全局设定 
*/ { ;不缩进块
#NoEnv
#Warn
#MaxThreadsPerHotkey 2
SendMode Input
SetWorkingDir %A_ScriptDir%
} ;不缩进块

/** 调用库
*/ { ;不缩进块
#Include ..\MyAhkModules\MyKey2.ahk ;按键相关库,所有函数导出到MyKey对象中
#Include ..\MyAhkModules\MyXZone.ahk ;导入自定义的游聚平台通用快捷键,用MyXZone_setHotkeys()函数设置
#Include ..\MyAhkModules\MyFaceDetector.ahk ;方向检测
#Include ..\MyAhkModules\MyMode.ahk ;模式管理模块
} ;不缩进块

/** 全局变量
*/ { ;不缩进块
  
/* 枚举量,全体大写
*/
;模式名称表和模式枚举量
global MODE_NAMES := ["关羽", "张飞", "赵云", "黄忠", "马超", "魔法张飞", "诸葛亮", "张辽", "貂蝉", "白甲黄忠"]
global MODE_GUANYU := 1, MODE_ZHANGFEI := 2, MODE_ZHAOYUN := 3, MODE_HUANGZHONG := 4, MODE_MACHAO := 5
global MODE_MOZHANG := 6, MODE_ZHUGELIANG := 7, MODE_ZHANGLIAO := 8, MODE_DIAOCHAN := 9, MODE_BAIHUANG := 10

  
/* 常量,全体大写
*/
global GAME_NAME := "三国战记" ;用于在Gui中显示游戏名字
global KEY_A := "x", KEY_B := "e" ;按键设置

/* 变量
*/
global exeTitle := "" ;接收游戏平台选择
global sbText := "" ;状态栏文本,也用于状态栏引用
global testParam1 := 300, testParam2 := 30, testParam3 := 50 ;测试参数

} ;不缩进块

/** 自定义函数,除Gui设置,Gui响应和热键绑定专用函数以外
*/ { ;不缩进块
  
/* 缩短MyKey模块的函数名称
*/
press(key, pressDuration := 100){ 
  return MyKey.press(key, pressDuration)
}
pressKeys(keys, delays, duration := 50){
  return MyKey.pressKeys(keys, delays, duration)
}
waitKeyUp(key, waitTime, waitDuration := 100){
  return MyKey.waitKeyUp(key, waitTime, waitDuration)
}
inputSkill(keys, delays){
  return MyKey.inputSkill(keys, delays)
}
autoFire(fireKey, autoKey, duration := 20, delay := 20){
  return MyKey.autoFire(fireKey, autoKey, duration, delay)
}

/* 游戏操作相关函数
*/

;前a
rSkill(){
  local direction := MyFaceDetector_getFace()
  pressKeys([direction, KEY_A], [30])
}

;26a或24a
drSkill(key){
  local direction := MyFaceDetector_getFace()
  inputSkill(["down", direction, KEY_A], [30, 30, 30])
  sleep, 30
  autoFire(KEY_A, key)
}

;46a或64a
lrSkill(){
  local direction2 := MyFaceDetector_getFace()
  local direction1 := (direction2 == "right") ? ("left") : ("right")
  press(direction1, 50)
  sleep, 50
  pressKeys([direction2, KEY_A], [30])
}

;82a
udSkill(){
  press("up", 50)
  sleep, 50
  pressKeys(["down", KEY_A], [30])
}

;28a
duSkill(){
  press("down", 50)
  sleep, 50
  pressKeys(["up", KEY_A], [30])
}

;22a
ddSkill(){
  press("down", 50)
  sleep, 50
  pressKeys(["down", KEY_A], [30])
}

;蹲下,攻击,站起
squatHit(){
  send, {down down}{%KEY_B% down}
  sleep, 50
  send, {down up}{%KEY_B% up}
  sleep, 50
  press(KEY_A, 30)
  sleep, 400
  press(KEY_B, 30)
}

;冲跑,测试发现原地起跑成功率很低,但向该方向移动或出招后成功率会提高很多,感觉是系统判断方式问题.
dash(){
  local direction := MyFaceDetector_getFace()
  press(direction, 80)
  sleep, 100
  press(direction, 200)
}

;冲跑攻击
dashAt(){
  local direction := MyFaceDetector_getFace()
  press(direction, 80)
  sleep, 80
  press(direction, 80)
  sleep, 80
  press(KEY_A)
}

;后转再反过来冲跑攻击
backDashAt(){
  local direction := MyFaceDetector_getFace()
  local backDirection := (direction == "right") ? ("left") : ("right")
  press(backDirection, 30)
  sleep, 30
  press(direction, 30)
  sleep, 30
  press(direction, 30)
  sleep, 100
  press(KEY_A)
}

} ;不缩进块

/** 设置Gui的函数 
*/ { ; 不缩进块

;选择游戏平台的UI
selectionUI(){ 
  Gui, New, , 选择游戏平台
  Gui, add, ListBox, VexeTitle Choose1, fbas.exe|X-Zone.exe
  Gui, add, Button, GButtonTitleSelect, 选择游戏平台
  Gui, show
}    

;设置游戏的主要UI,title是平台的exe标题,目前是fbas.exe|X-Zone.exe二选一
setupUI(title) {
  Gui, MainUI:New, , % SubStr(title, 1, 1) . GAME_NAME
  Gui, Add, Text, x+20 y+20, testParam1： ;
  Gui, Add, Edit, xp+80 yp-3 W60 vtestParam1, %testParam1% ;测试参数1
  Gui, Add, Text, xp-80 yp+30, testParam2： ;
  Gui, Add, Edit, xp+80 yp-3 W60 vtestParam2, %testParam2% ;测试参数2
  Gui, Add, Text, xp-80 yp+30, testParam3： ;
  Gui, Add, Edit, xp+80 yp-3 W60 vtestParam3, %testParam3% ;测试参数3
  Gui, Add, Button, xp-80 yp+30 gButtonSubmit_, 提交 ;提交,运行ButtonSubmit_()函数
  Gui, Add, Button, xp+100 gButtonExit, 退出 ;结束app
  Gui, Add, StatusBar, vsbText ;状态栏并非默认,更新文本必须用:GuiControl, MainUI:Text, sbText, 新文本 
  Gui, MainUI:+AlwaysOnTop
  Gui, MainUI:Show, X1085 Y250
}

} ;不缩进块

/** Gui响应函数
*/ { ;不缩进块

ButtonSubmit_(){
  Gui, Submit, NoHide ; 保存用户输入后每个控件的数据,NoHide可以在提交数据后保持窗体显示
  MsgBox, You have submit your changes!
}

ButtonExit(){
  ExitApp
}

;只能用在不设定名字的Gui,所以两个Gui只有一个生效,我选择了让启动时的那个生效
GuiClose(){
  ExitApp
}

;选择游戏平台后的操作
ButtonTitleSelect(){
  Gui, Submit, Hide
  setupUI(exeTitle)
  setupHotkeys(exeTitle)
  MyMode_setup(MODE_NAMES, exeTitle, "RControl", guiName := "MainUI", guiVarName := "sbText")
  MyMode_setIndex(1)
}

} ;不缩进块

/** 快捷键响应函数
*/ { ;不缩进块
  
;w键连发
KeyW(){
  ;press(KEY_A, 50)
  ;sleep, 80
  autoFire(KEY_A, "w", 30, 30)
}

;q,r,2,3的作用各人不同,一般来说q是最常用的必杀技,r是第二常用的,而2,3则是各人的补充,有人是超必杀,也有人是蹲砍之类的操作
KeyQ(){
  local mode := MyMode_getIndex()
  if ((mode == MODE_GUANYU) or (mode == MODE_HUANGZHONG) or (mode == MODE_DIAOCHAN) or (mode == MODE_BAIHUANG)) {
    ;关羽,黄忠,貂蝉,白黄的下前a
    drSkill("q")
  } else if ((mode == MODE_ZHANGFEI) or (mode == MODE_MOZHANG) or (mode == MODE_ZHANGLIAO)) {
    ;张飞,魔张,张辽的后前a
    lrSkill()
  } else if ((mode == MODE_ZHAOYUN)) {
    ;赵云的下上a
    duSkill()
  } else if ((mode == MODE_MACHAO)) {
    ;马超的上下a
    udSkill()
  }
}
KeyR(){
  local mode := MyMode_getIndex()
  if ((mode == MODE_GUANYU) or (mode == MODE_HUANGZHONG) or (mode == MODE_BAIHUANG)) {
    ;关羽,黄忠,白黄的前a
    rSkill()
  } else if ((mode == MODE_ZHANGFEI) or (mode == MODE_MOZHANG)) {
    ;张飞,魔张的冲撞斩
    dashAt()
  } else if ((mode == MODE_ZHANGLIAO) or (mode == MODE_ZHAOYUN)) {
    ;赵云,张辽的下前a
    drSkill("r")
  } else if ((mode == MODE_MACHAO)) {
    ;马超的超必杀
    duSkill()
  }
}
Key2(){
  local mode := MyMode_getIndex()
  if ((mode == MODE_GUANYU) or (mode == MODE_DIAOCHAN)) {
    ;关羽,貂蝉的超必杀
    duSkill()
  } else if ((mode == MODE_HUANGZHONG) or (mode == MODE_BAIHUANG)) {
    ;黄忠,白黄的转身冲撞斩
    backDashAt()
  } else if ((mode == MODE_ZHANGFEI) or (mode == MODE_MOZHANG)) {
    ;张飞,魔张的下前a
    drSkill("2")
  } else if ((mode == MODE_MACHAO) or (mode == MODE_ZHANGLIAO)) {
    ;马超,张辽的下蹲攻击再站起
    squatHit()
  } else if ((mode == MODE_ZHAOYUN)) {
    ;赵云的超必杀
    udSkill()
  }
}
Key3(){
  local mode := MyMode_getIndex()
  if ((mode == MODE_GUANYU) or (mode == MODE_DIAOCHAN)) {
    ;关羽,貂蝉的爆气必杀
    lrSkill()
  } else if ((mode == MODE_HUANGZHONG) or (mode == MODE_BAIHUANG)) {
    ;黄忠,白黄,张辽的超必杀
    udSkill()
  } else if ((mode == MODE_ZHANGFEI) or (mode == MODE_MOZHANG)) {
    ;张飞,魔张的下下冲撞
    ddSkill()
  } else if ((mode == MODE_ZHANGLIAO)) {
    ;张辽的超必杀
    duSkill()
  }
}

} ;不缩进块

/** 根据游戏平台设置快捷键的函数 
*/ { ;不缩进块
setupHotkeys(title){
  local wTitle := "ahk_exe " . title
  MyFaceDetector_setup(title)
  switch (wTitle) {
    case "ahk_exe fbas.exe": { ;模拟器fbas
      Hotkey, IfWinActive, %wTitle%
      ;这里设置模拟器fbas热键
      Hotkey, ~w, KeyW
      Hotkey, ~r, KeyR
      Hotkey, ~q, KeyQ
      Hotkey, ~2, Key2
      Hotkey, ~3, Key3
      Hotkey, IfWinActive
    } case "ahk_exe X-Zone.exe": { ;游聚平台
      MyXZone_setHotkeys({"KeyA": "x", "autoFireKey": "w", "KeyAB": "p"}) ;游聚平台通用热键
      Hotkey, IfWinActive, %wTitle%
      ;这里设置游聚平台热键
      Hotkey, ~r, KeyR
      Hotkey, ~q, KeyQ
      Hotkey, ~2, Key2
      Hotkey, ~3, Key3
      Hotkey, IfWinActive
    } 
  }
}

} ;不缩进块

/** 主函数,这里是只显示选择平台的UI,之后交给选择后的函数去处理
*/ { ;不缩进块
main() {
  ;设置游戏平台选择UI
  selectionUI()
}
} ;不缩进块

/** 运行 
*/
main()
return
